package com.brillilab.service.core.system.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.brillilab.common.redis.RedisCache;
import com.brillilab.dao.mapper.kit.ReagentFieldDataMapper;
import com.brillilab.dao.mapper.kit.ReagentSearchFieldMapper;
import com.brillilab.dao.mapper.kit.ReagentTypeMapper;
import com.brillilab.dao.mapper.system.DictMapper;
import com.brillilab.domain.enums.common.BoolEnum;
import com.brillilab.domain.enums.common.IsDeleteEnum;
import com.brillilab.domain.enums.experiment.PlateTypeEnum;
import com.brillilab.domain.po.kit.ReagentFieldData;
import com.brillilab.domain.po.kit.ReagentSearchField;
import com.brillilab.domain.po.kit.ReagentType;
import com.brillilab.domain.po.system.Dict;
import com.brillilab.domain.vo.system.DictDutyYearVo;
import com.brillilab.domain.vo.system.ReagentFieldDataVo;
import com.brillilab.service.core.system.IDictService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 地区服务
 *
 * @author wmh
 */
@Service
@SuppressWarnings("unchecked")
public class DictServiceImpl implements IDictService {

	@Resource
	private DictMapper dictMapper;
	@Resource
	private ReagentTypeMapper reagentTypeMapper;
	@Resource
	private ReagentFieldDataMapper reagentFieldDataMapper;
	@Resource
	private ReagentSearchFieldMapper reagentSearchFieldMapper;

	@Resource
	private RedisCache redisCache;

	@Override
	public Dict insert(Dict entity) {
		Integer insert = dictMapper.insert(entity);
		Assert.isTrue(insert == 1, "添加失败");
		return entity;
	}

	@Override
	public boolean deleteById(Long id) {
		Integer b = dictMapper.deleteById(id);
		return b == 1 ? true : false;
	}

	@Override
	public boolean updateById(Dict dict) {
		Integer b = dictMapper.updateById(dict);
		return b == 1 ? true : false;
	}

	@Override
	public Dict selectById(Long id) {
		return dictMapper.selectById(id);
	}

	@Override
	public Map<String, List<Dict>> getUnit() {

		Map<String, List<Dict>> map = (Map<String, List<Dict>>) redisCache.getObj("system:SYSTEM_UNIT_GROUP");
		if (map == null) {
			LambdaQueryWrapper<Dict> wrapper = new LambdaQueryWrapper<>();
			wrapper.in(Dict::getType, "unit_quality", "unit_volume", "unit_concentration", "unit_active", "unit_other");
			wrapper.orderByDesc(Dict::getType, Dict::getSortNo);
			List<Dict> allList = dictMapper.selectList(wrapper);
			Map<String, List<Dict>> collect = allList.stream().collect(Collectors.groupingBy(Dict::getType));

			map = new LinkedHashMap<>();
			map.put("质量", collect.get("unit_quality"));
			map.put("体积", collect.get("unit_volume"));
			map.put("摩尔", collect.get("unit_concentration"));
			map.put("活性", collect.get("unit_active"));
			List<Dict> unitOtherList = collect.get("unit_other");
			for (Iterator<Dict> iterator = unitOtherList.iterator(); iterator.hasNext();) {
				Dict dict = iterator.next();
				if (dict.getCode() == 21 || dict.getCode() == 45) {
					iterator.remove();
				}
			}
			map.put("个数", unitOtherList);
			redisCache.set("system:SYSTEM_UNIT_GROUP", map, 600);
		}
		return map;
	}

	public List<Dict> getAllUnit() {
		List<Dict> list = (List<Dict>) redisCache.getObj("system:SYSTEM_UNIT_ALL2");
		if (list == null) {
			LambdaQueryWrapper<Dict> wrapper = new LambdaQueryWrapper<>();
			wrapper.in(Dict::getType, "unit_quality", "unit_volume", "unit_concentration", "unit_active", "unit_other");
			list = dictMapper.selectList(wrapper);
			for (Iterator<Dict> iterator = list.iterator(); iterator.hasNext();) {
				Dict dict = iterator.next();
				if (dict.getCode() == 21 || dict.getCode() == 45) {
					iterator.remove();
				}
			}
			redisCache.set("system:SYSTEM_UNIT_ALL2", list, 600);
		}
		return list;
	}

	@Override
	public Dict selectOne(Integer code, String type) {
		return dictMapper.selectOne(new LambdaQueryWrapper<Dict>().eq(Dict::getCode, code).eq(Dict::getType, type));
	}

	@Override
	public List<Dict> getZone() {
		List<Dict> list = (List<Dict>) redisCache.getObj("system:SYSTEM_ZONE_LIST");
		if (list == null) {
			LambdaQueryWrapper<Dict> wrapper = new LambdaQueryWrapper<>();
			wrapper.eq(Dict::getType, "zone");
			list = dictMapper.selectList(wrapper);
			redisCache.set("system:SYSTEM_ZONE_LIST", list, 600);
		}
		return list;
	}

	@Override
	public List<Dict> getBoxColor() {
		List<Dict> list = (List<Dict>) redisCache.getObj("system:SYSTEM_BOX_COLOR_LIST");
		if (list == null) {
			LambdaQueryWrapper<Dict> wrapper = new LambdaQueryWrapper<>();
			wrapper.eq(Dict::getType, "box_color");
			list = dictMapper.selectList(wrapper);
			redisCache.set("system:SYSTEM_BOX_COLOR_LIST", list, 600);
		}
		return list;
	}

	@Override
	public List<Dict> getBoxSize() {
		List<Dict> list = (List<Dict>) redisCache.getObj("system:SYSTEM_BOX_SIZE_LIST");
		if (list == null) {
			LambdaQueryWrapper<Dict> wrapper = new LambdaQueryWrapper<>();
			wrapper.eq(Dict::getType, "box_size");
			list = dictMapper.selectList(wrapper);
			redisCache.set("system:SYSTEM_BOX_SIZE_LIST", list, 600);
		}
		return list;
	}

	@Override
	public List<Dict> getTubeSize() {
		List<Dict> list = (List<Dict>) redisCache.getObj("system:SYSTEM_TUBE_SIZE_LIST");
		if (list == null) {
			LambdaQueryWrapper<Dict> wrapper = new LambdaQueryWrapper<>();
			wrapper.eq(Dict::getType, "tube_size");
			list = dictMapper.selectList(wrapper);
			redisCache.set("system:SYSTEM_TUBE_SIZE_LIST", list, 600);
		}
		return list;
	}

	@Override
	public List<Dict> getDuty() {
		List<Dict> list = (List<Dict>) redisCache.getObj("system:SYSTEM_USER_DUTY_LIST");
		if (list == null) {
			LambdaQueryWrapper<Dict> wrapper = new LambdaQueryWrapper<>();
			wrapper.eq(Dict::getType, "user_duty");
			list = dictMapper.selectList(wrapper);
			redisCache.set("system:SYSTEM_USER_DUTY_LIST", list, 600);
		}
		return list;
	}
	/*@Override
	public List<Dict> getDutyYearList(){

		List<Dict> list = new ArrayList<>();
		LambdaQueryWrapper<Dict> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(Dict::getType, "duty_year");
		list = dictMapper.selectList(wrapper);
		redisCache.set("system:SYSTEM_DUTY_YEAR_LIST", list, 600);
		return list;
	}*/

	@Override
	public List<DictDutyYearVo> getDutyYearList(){
		List<DictDutyYearVo> list = new ArrayList<>();
		list = dictMapper.selectDutyYear();
		return list;
	}

	@Override
	public Map<Integer, String> getUnitMap() {
		Map<Integer, String> map = (Map<Integer, String>) redisCache.getObj("system:SYSTEM_UNIT_MAP");
		if (map == null) {
			LambdaQueryWrapper<Dict> wrapper = new LambdaQueryWrapper<>();
			wrapper.in(Dict::getType, "unit_quality", "unit_volume", "unit_concentration", "unit_active", "unit_other");
			List<Dict> list = dictMapper.selectList(wrapper);
			map = list.stream().collect(Collectors.toMap(Dict::getCode, Dict::getName));
			redisCache.set("system:SYSTEM_UNIT_MAP", map, 600);
		}
		return map;
	}

	@Override
	public Map<Integer, String> getZoneMap() {
		Map<Integer, String> map = (Map<Integer, String>) redisCache.getObj("system:SYSTEM_ZONE_MAP");
		if (map == null) {
			LambdaQueryWrapper<Dict> wrapper = new LambdaQueryWrapper<>();
			wrapper.eq(Dict::getType, "zone");
			List<Dict> list = dictMapper.selectList(wrapper);
			map = list.stream().collect(Collectors.toMap(Dict::getCode, Dict::getName));
			redisCache.set("system:SYSTEM_ZONE_MAP", map, 600);
		}
		return map;
	}

	@Override
	public Map<Integer, String> getUserDutyMap() {
		Map<Integer, String> map = (Map<Integer, String>) redisCache.getObj("system:SYSTEM_USER_DUTY_MAP");
		if (map == null) {
			LambdaQueryWrapper<Dict> wrapper = new LambdaQueryWrapper<>();
			wrapper.in(Dict::getType, "user_duty_new","duty_doctor","duty_master");
			List<Dict> list = dictMapper.selectList(wrapper);
			map = list.stream().collect(Collectors.toMap(Dict::getCode, Dict::getName));
			redisCache.set("system:SYSTEM_USER_DUTY_MAP", map, 600);
		}
		return map;
	}

	@Override
	public Map<Integer, String> getDutyMap() {
		Map<Integer, String> map = (Map<Integer, String>) redisCache.getObj("system:SYSTEM_DUTY_MAP");
		if (map == null) {
			LambdaQueryWrapper<Dict> wrapper = new LambdaQueryWrapper<>();
			wrapper.eq(Dict::getType, "user_duty");
			List<Dict> list = dictMapper.selectList(wrapper);
			map = list.stream().collect(Collectors.toMap(Dict::getCode, Dict::getName));
			redisCache.set("system:SYSTEM_DUTY_MAP", map, 600);
		}
		return map;
	}

	@Override
	public Map<Long, String> getReagentTypeMap(Long labId) {
		LambdaQueryWrapper<ReagentType> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(ReagentType::getIsDelete, BoolEnum.FALSE.getValue());
		if(labId==null) {
			queryWrapper.isNull(ReagentType::getLabId);
		}else {
			queryWrapper.and(wrapper -> wrapper.eq(ReagentType::getLabId, labId).or().isNull(ReagentType::getLabId));
		}
		List<ReagentType> list = reagentTypeMapper.selectList(queryWrapper);
		return list.stream().collect(Collectors.toMap(ReagentType::getId, ReagentType::getName));
	}

	@Override
	public List<Dict> getWarnamount() {
		List<Dict> list = (List<Dict>) redisCache.getObj("system:SYSTEM_WARNAMOUNT_LIST");
		if (list == null) {
			LambdaQueryWrapper<Dict> wrapper = new LambdaQueryWrapper<>();
			wrapper.eq(Dict::getType, "warnamount");
			list = dictMapper.selectList(wrapper);
			redisCache.set("system:SYSTEM_WARNAMOUNT_LIST", list, 600);
		}
		return list;
	}

	@Override
	public List<ReagentFieldDataVo> getReagentFieldData() {
		List<ReagentFieldDataVo> voList = new ArrayList<>();
		LambdaQueryWrapper<ReagentFieldData> wrapper = new LambdaQueryWrapper<>();
		wrapper.orderByAsc(ReagentFieldData::getReagentTypeId);
		wrapper.orderByAsc(ReagentFieldData::getFieldName);
		wrapper.orderByDesc(ReagentFieldData::getSort);
		wrapper.orderByAsc(ReagentFieldData::getFieldData);
		List<ReagentFieldData> selectList = reagentFieldDataMapper.selectList(wrapper);
		if (selectList != null && selectList.size() > 0) {
			Map<Long, List<ReagentFieldData>> map = selectList.stream()
					.collect(Collectors.groupingBy(ReagentFieldData::getReagentTypeId));
			map.keySet().forEach(reagentTypeId -> {
				Map<String, List<ReagentFieldData>> map2 = map.get(reagentTypeId).stream()
						.collect(Collectors.groupingBy(ReagentFieldData::getFieldName));
				map2.keySet().forEach(fieldName -> {
					ReagentFieldDataVo vo = new ReagentFieldDataVo();
					vo.setReagentTypeId(reagentTypeId);
					vo.setFieldName(fieldName);
					List<String> fieldDataList = map2.get(fieldName).stream().map(ReagentFieldData::getFieldData)
							.collect(Collectors.toList());
					vo.setFieldDataList(fieldDataList);
					voList.add(vo);
				});
			});
		}
		return voList;
	}

	@Override
	public List<ReagentSearchField> getReagentSearchField(Long reagentTypeId) {
		LambdaQueryWrapper<ReagentSearchField> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(ReagentSearchField::getReagentTypeId, reagentTypeId);
		wrapper.orderByAsc(ReagentSearchField::getSort);
		return reagentSearchFieldMapper.selectList(wrapper);
	}

	@Override
	public List<Dict> getPlateType() {
		return dictMapper.selectList(new LambdaQueryWrapper<Dict>().in(Dict::getType,
				PlateTypeEnum.PORE_PLATE.getName(), PlateTypeEnum.GUM_PLATE.getName(),
				PlateTypeEnum.CULTURE_DISH.getName(), PlateTypeEnum.CULTURE_BOTTLER.getName()));
	}

	@Override
	public Map<Integer, String> getPlateTypeMap() {
		List<Dict> dict = dictMapper.selectList(new LambdaQueryWrapper<Dict>().eq(Dict::getType, "plate_type"));
		return dict.stream().collect(Collectors.toMap(Dict::getCode, Dict::getName));
	}

}
